package com.jiguang.property.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jiguang.property.dto.BuildInfoDTO;
import com.jiguang.property.dto.HostelInfoDTO;
import com.jiguang.property.dto.UserInfoDTO;
import com.jiguang.property.entity.*;
import com.jiguang.property.handler.GuliException;
import com.jiguang.property.mapper.HostelInfoMapper;
import com.jiguang.property.service.CostInfoService;
import com.jiguang.property.service.HostelInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiguang.property.service.UpkeepInfoService;
import com.jiguang.property.service.UserService;
import com.jiguang.property.utils.JwtUtils;
import com.jiguang.property.utils.Result;
import io.netty.util.internal.StringUtil;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author testjava
 * @since 2025-03-15
 */
@Service
public class HostelInfoServiceImpl extends ServiceImpl<HostelInfoMapper, HostelInfo> implements HostelInfoService {
    @Autowired
    private UserService userService;
    @Autowired
    private JwtUtils tokenManager;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UpkeepInfoService upkeepInfoService;
    @Autowired
    private CostInfoService costInfoService;


    @SneakyThrows
    @Override
    public Result listHostelInfo(HostelInfoDTO hostelInfoDTO) {
        //创建分页对象
        Page<HostelInfo> page = new Page<>(hostelInfoDTO.getPageNow(),hostelInfoDTO.getPageSize());

        QueryWrapper<HostelInfo> wrapper = new QueryWrapper<>();
        //判断楼宇信息是否为空
        if (!StringUtil.isNullOrEmpty(hostelInfoDTO.getHostelCode())){
            wrapper.like("hostel_code",hostelInfoDTO.getHostelCode());
        }
        //判断关联楼宇ID是否为空
        if (!StringUtil.isNullOrEmpty(hostelInfoDTO.getBuildId())){
            wrapper.like("build_id",hostelInfoDTO.getBuildId());
        }
        if(!StringUtil.isNullOrEmpty(hostelInfoDTO.getUserId())){
            wrapper.eq("user_id",hostelInfoDTO.getUserId());
        }

        //权限控制
        //通过工具类获取Request对象
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = sra.getRequest();
        //获取用户名
        //需要通过解析token获取
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)){
            return Result.error().code(403).message("登陆超时，请重新登陆");
        }
        String userId = tokenManager.getUserFromToken(token);

        //从redis中获取用户信息
        String redisKey = "login:" + userId;
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        String cacheObject = (String) redisTemplate.opsForValue().get(redisKey);
        if (StringUtils.isEmpty(cacheObject)) {
            return Result.error().code(403).message("登陆超时，请重新登陆");
        }
        UserInfoDTO ucenter = new ObjectMapper().readValue(cacheObject.toString(), UserInfoDTO.class);
        if (ucenter.getPosition() == 0){
            wrapper.eq("user_id",userId);
        }

        wrapper.eq("is_delete",0);
        wrapper.orderByDesc("update_time");

        Page<HostelInfo> buildInfoPage = (Page<HostelInfo>) baseMapper.selectPage(page,wrapper);

        return Result.ok().message("查询成功").data("hostelInfos", buildInfoPage.getRecords()).data("total",buildInfoPage.getTotal());
    }

    @Override
    public Result deleteHostelInfo(String hostelIds) {
        List<String> ids = Arrays.asList(hostelIds.split(","));

        //已出售房屋不能删除
        List<HostelInfo> hostelInfos = baseMapper.selectBatchIds(ids);
        for (HostelInfo hostelInfo : hostelInfos) {
            if (hostelInfo.getStatus() == 1){
                return  Result.error().message("已出售房屋无法删除");
            }
        }

        baseMapper.deleteBatchIds(ids);
        return Result.ok().message("删除成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateOrAddHostelInfo(HostelInfoDTO hostelInfoDTO) {
        HostelInfo hostelInfo = new HostelInfo();
        BeanUtils.copyProperties(hostelInfoDTO,hostelInfo);

        //如果是已出售验证关联用户
        if (hostelInfoDTO.getStatus() == 1 && StringUtils.isEmpty(hostelInfoDTO.getUserId())){
            return Result.error().message("请选择出售的业主");
        }

        if (hostelInfoDTO.getStatus() == 1){
            //验证是否存在该用户
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.eq("is_delete",0);
            userQueryWrapper.eq("id",hostelInfoDTO.getUserId());
            User user = userService.getOne(userQueryWrapper);

            if (user == null){
                return Result.error().message("不存在该业主");
            }

            //如果该用户不是业主，需要将用户设置为业主
            if (user.getPosition() != 0){
                user.setPosition(0);
                userService.updateById(user);
            }
        }

        if (StringUtil.isNullOrEmpty(hostelInfo.getId())){
            boolean b = existHostel(hostelInfoDTO);
            if (b) {return Result.error().message("当前房屋存在该房间房");}

            baseMapper.insert(hostelInfo);
        }else{
            boolean b = existHostel(hostelInfoDTO);
            if (b) {return Result.error().message("房屋信息有误");}

            //如果是将出售房屋转成未出售||房屋业主转换了
            HostelInfo hostelInfoOld = baseMapper.selectById(hostelInfo.getId());
            if ((hostelInfoOld.getStatus() == 1 && hostelInfo.getStatus() == 0)
                    || !hostelInfoOld.getUserId().equals(hostelInfo.getUserId())){
                //查询原来的业主是否存在欠费
                QueryWrapper<CostInfo> cWrapper = new QueryWrapper<>();
                cWrapper.eq("status",0);
                List<CostInfo> list = costInfoService.list(cWrapper);
                if(!CollectionUtils.isEmpty(list)){
                    throw new GuliException(111001,"业主存在欠费，无法更改房屋所属人");
                }

                QueryWrapper<UpkeepInfo> uWrapper = new QueryWrapper<>();
                uWrapper.eq("status",1).or().eq("status",2);
                List<UpkeepInfo> upkeepInfos = upkeepInfoService.list(uWrapper);
                if(!CollectionUtils.isEmpty(upkeepInfos)){
                    throw new GuliException(111001,"业主存在欠费，无法更改房屋所属人");
                }

                //判断该业主是否还有房屋，否则修改为普通用户权限
                QueryWrapper<HostelInfo> hWrapper = new QueryWrapper<>();
                hWrapper.eq("user_id",hostelInfoOld.getUserId());
                Integer count = baseMapper.selectCount(hWrapper);
                if (count == 0){
                    //修改用户权限
                    User user = new User();
                    user.setId(hostelInfoOld.getUserId());
                    user.setPosition(4);
                    userService.updateById(user);
                }
            }

            baseMapper.updateById(hostelInfo);
        }


        return Result.ok().message("成功");
    }

    private boolean existHostel(HostelInfoDTO hostelInfoDTO) {
        QueryWrapper<HostelInfo> wrapper = new QueryWrapper<>();
        wrapper.eq("hostel_code",hostelInfoDTO.getHostelCode());
        wrapper.eq("build_id",hostelInfoDTO.getBuildId());
        HostelInfo hostelInfo = baseMapper.selectOne(wrapper);

        if (hostelInfo != null){
            if (!StringUtils.isEmpty(hostelInfo.getId()) && !hostelInfo.getId().equals(hostelInfoDTO.getId())){
                return true;
            }else if(!StringUtils.isEmpty(hostelInfo.getId()) && !hostelInfo.getStatus().equals(hostelInfoDTO.getStatus()) && hostelInfoDTO.getStatus() == 1 && StringUtils.isEmpty(hostelInfoDTO.getUserId())){
                //判断一下，如果编辑状态之前是未出售，现在是已出售，那么业主ID不能未空
                return true;
            }else if (StringUtils.isEmpty(hostelInfoDTO.getId())){
                return true;
            }else{
                return false;
            }
        }
        return false;
    }
}
